home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / POV-Ray 3.0.2 / src / SOURCE / BEZIER.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-25  |  44.5 KB  |  2,346 lines  |  [TEXT/CWIE]

  1. /****************************************************************************
  2. *                   bezier.c
  3. *
  4. *  This module implements the code for Bezier bicubic patch shapes
  5. *
  6. *  This file was written by Alexander Enzmann.  He wrote the code for
  7. *  bezier bicubic patches and generously provided us these enhancements.
  8. *
  9. *  from Persistence of Vision(tm) Ray Tracer
  10. *  Copyright 1996 Persistence of Vision Team
  11. *---------------------------------------------------------------------------
  12. *  NOTICE: This source code file is provided so that users may experiment
  13. *  with enhancements to POV-Ray and to port the software to platforms other
  14. *  than those supported by the POV-Ray Team.  There are strict rules under
  15. *  which you are permitted to use this file.  The rules are in the file
  16. *  named POVLEGAL.DOC which should be distributed with this file. If
  17. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  18. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  19. *  Forum.  The latest version of POV-Ray may be found there as well.
  20. *
  21. * This program is based on the popular DKB raytracer version 2.12.
  22. * DKBTrace was originally written by David K. Buck.
  23. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  24. *
  25. *****************************************************************************/
  26.  
  27. #include "frame.h"
  28. #include "vector.h"
  29. #include "povproto.h"
  30. #include "bezier.h"
  31. #include "matrices.h"
  32. #include "objects.h"
  33. #include "povray.h"
  34.  
  35.  
  36.  
  37. /*****************************************************************************
  38. * Local preprocessor defines
  39. ******************************************************************************/
  40.  
  41. #define BEZIER_EPSILON 1.0e-10
  42.  
  43. #define BEZIER_TOLERANCE 1.0e-5
  44.  
  45.  
  46.  
  47. /*****************************************************************************
  48. * Local typedefs
  49. ******************************************************************************/
  50.  
  51.  
  52.  
  53. /*****************************************************************************
  54. * Static functions
  55. ******************************************************************************/
  56.  
  57. static int InvertMatrix PARAMS((VECTOR in[3], VECTOR out[3]));
  58. static void bezier_value PARAMS((VECTOR(*Control_Points)[4][4], DBL u0, DBL v0, VECTOR P, VECTOR N));
  59. static int intersect_subpatch PARAMS((BICUBIC_PATCH *, RAY *, VECTOR [3], DBL [3], DBL [3], DBL *, VECTOR , VECTOR , DBL *, DBL *));
  60. static void find_average PARAMS((int, VECTOR *, VECTOR , DBL *));
  61. static int spherical_bounds_check PARAMS((RAY *, VECTOR , DBL));
  62. static int intersect_bicubic_patch0 PARAMS((RAY *, BICUBIC_PATCH *, ISTACK *));
  63. static DBL point_plane_distance PARAMS((VECTOR , VECTOR , DBL *));
  64. static DBL determine_subpatch_flatness PARAMS((VECTOR(*)[4][4]));
  65. static int flat_enough PARAMS((BICUBIC_PATCH *, VECTOR(*)[4][4]));
  66. static void bezier_bounding_sphere PARAMS((VECTOR(*)[4][4], VECTOR , DBL *));
  67. static int bezier_subpatch_intersect PARAMS((RAY *, BICUBIC_PATCH *, VECTOR(*)[4][4], DBL, DBL, DBL, DBL, ISTACK *));
  68. static void bezier_split_left_right PARAMS((VECTOR(*)[4][4], VECTOR(*)[4][4], VECTOR(*)[4][4]));
  69. static void bezier_split_up_down PARAMS((VECTOR(*)[4][4], VECTOR(*)[4][4], VECTOR(*)[4][4]));
  70. static int bezier_subdivider PARAMS((RAY *, BICUBIC_PATCH *, VECTOR(*)[4][4], DBL, DBL, DBL, DBL, int, ISTACK *));
  71. static void bezier_tree_deleter PARAMS((BEZIER_NODE *Node));
  72. static BEZIER_NODE *bezier_tree_builder PARAMS((BICUBIC_PATCH *Object, VECTOR(*Patch)[4][4], DBL u0, DBL u1, DBL v0, DBL v1, int depth));
  73. static int bezier_tree_walker PARAMS((RAY *, BICUBIC_PATCH *, BEZIER_NODE *, ISTACK *));
  74. static BEZIER_NODE *create_new_bezier_node PARAMS((void));
  75. static BEZIER_VERTICES *create_bezier_vertex_block PARAMS((void));
  76. static BEZIER_CHILDREN *create_bezier_child_block PARAMS((void));
  77. static int subpatch_normal PARAMS((VECTOR v1, VECTOR v2, VECTOR v3, VECTOR Result, DBL *d));
  78. static int All_Bicubic_Patch_Intersections PARAMS((OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack));
  79. static int Inside_Bicubic_Patch PARAMS((VECTOR IPoint, OBJECT *Object));
  80. static void Bicubic_Patch_Normal PARAMS((VECTOR Result, OBJECT *Object, INTERSECTION *Inter));
  81. static void *Copy_Bicubic_Patch PARAMS((OBJECT *Object));
  82. static void Translate_Bicubic_Patch PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  83. static void Rotate_Bicubic_Patch PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  84. static void Scale_Bicubic_Patch PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  85. static void Transform_Bicubic_Patch PARAMS((OBJECT *Object, TRANSFORM *Trans));
  86. static void Invert_Bicubic_Patch PARAMS((OBJECT *Object));
  87. static void Destroy_Bicubic_Patch PARAMS((OBJECT *Object));
  88.  
  89.  
  90.  
  91. /*****************************************************************************
  92. * Local variables
  93. ******************************************************************************/
  94.  
  95. static METHODS Bicubic_Patch_Methods =
  96. {
  97.   All_Bicubic_Patch_Intersections,
  98.   Inside_Bicubic_Patch, Bicubic_Patch_Normal, Copy_Bicubic_Patch,
  99.   Translate_Bicubic_Patch, Rotate_Bicubic_Patch,
  100.   Scale_Bicubic_Patch, Transform_Bicubic_Patch, Invert_Bicubic_Patch,
  101.   Destroy_Bicubic_Patch
  102. };
  103.  
  104. static int max_depth_reached;
  105.  
  106. static DBL C[4] = { 1.0, 3.0, 3.0, 1.0 };
  107.  
  108.  
  109.  
  110. /*****************************************************************************
  111. *
  112. * FUNCTION
  113. *
  114. *   create_new_bezier_node
  115. *
  116. * INPUT
  117. *   
  118. * OUTPUT
  119. *   
  120. * RETURNS
  121. *   
  122. * AUTHOR
  123. *
  124. *   Alexander Enzmann
  125. *   
  126. * DESCRIPTION
  127. *
  128. *   -
  129. *
  130. * CHANGES
  131. *
  132. *   -
  133. *
  134. ******************************************************************************/
  135.  
  136. static BEZIER_NODE *create_new_bezier_node()
  137. {
  138.   BEZIER_NODE *Node = (BEZIER_NODE *)POV_MALLOC(sizeof(BEZIER_NODE), "bezier node");
  139.   
  140.   Node->Data_Ptr = NULL;
  141.  
  142.   return (Node);
  143. }
  144.  
  145.  
  146.  
  147. /*****************************************************************************
  148. *
  149. * FUNCTION
  150. *
  151. *   create_bezier_vertex_block
  152. *
  153. * INPUT
  154. *   
  155. * OUTPUT
  156. *   
  157. * RETURNS
  158. *   
  159. * AUTHOR
  160. *
  161. *   Alexander Enzmann
  162. *   
  163. * DESCRIPTION
  164. *
  165. *   -
  166. *
  167. * CHANGES
  168. *
  169. *   -
  170. *
  171. ******************************************************************************/
  172.  
  173. static BEZIER_VERTICES *create_bezier_vertex_block()
  174. {
  175.   BEZIER_VERTICES *Vertices;
  176.  
  177.   Vertices = (BEZIER_VERTICES *)POV_MALLOC(sizeof(BEZIER_VERTICES), "bezier vertices");
  178.   
  179.   return (Vertices);
  180. }
  181.  
  182.  
  183.  
  184. /*****************************************************************************
  185. *
  186. * FUNCTION
  187. *
  188. *   create_bezier_child_block
  189. *
  190. * INPUT
  191. *   
  192. * OUTPUT
  193. *   
  194. * RETURNS
  195. *   
  196. * AUTHOR
  197. *
  198. *   Alexander Enzmann
  199. *   
  200. * DESCRIPTION
  201. *
  202. *   -
  203. *
  204. * CHANGES
  205. *
  206. *   -
  207. *
  208. ******************************************************************************/
  209.  
  210. static BEZIER_CHILDREN *create_bezier_child_block()
  211. {
  212.   BEZIER_CHILDREN *Children;
  213.   
  214.   Children = (BEZIER_CHILDREN *)POV_MALLOC(sizeof(BEZIER_CHILDREN), "bezier children");
  215.   
  216.   return (Children);
  217. }
  218.  
  219.  
  220.  
  221. /*****************************************************************************
  222. *
  223. * FUNCTION
  224. *
  225. *   bezier_tree_builder
  226. *
  227. * INPUT
  228. *   
  229. * OUTPUT
  230. *   
  231. * RETURNS
  232. *   
  233. * AUTHOR
  234. *
  235. *   Alexander Enzmann
  236. *   
  237. * DESCRIPTION
  238. *
  239. *   -
  240. *
  241. * CHANGES
  242. *
  243. *   -
  244. *
  245. ******************************************************************************/
  246.  
  247. static BEZIER_NODE *bezier_tree_builder(Object, Patch, u0, u1, v0, v1, depth)
  248. BICUBIC_PATCH *Object;
  249. VECTOR(*Patch)[4][4];
  250. DBL u0, u1, v0, v1;
  251. int depth;
  252. {
  253.   VECTOR Lower_Left[4][4], Lower_Right[4][4];
  254.   VECTOR Upper_Left[4][4], Upper_Right[4][4];
  255.   BEZIER_CHILDREN *Children;
  256.   BEZIER_VERTICES *Vertices;
  257.   BEZIER_NODE *Node = create_new_bezier_node();
  258.   
  259.   if (depth > max_depth_reached)
  260.   {
  261.     max_depth_reached = depth;
  262.   }
  263.   
  264.   /* Build the bounding sphere for this subpatch. */
  265.   
  266.   bezier_bounding_sphere(Patch, Node->Center, &(Node->Radius_Squared));
  267.   
  268.   /*
  269.    * If the patch is close to being flat, then just perform
  270.    * a ray-plane intersection test.
  271.    */
  272.   
  273.   if (flat_enough(Object, Patch))
  274.   {
  275.     /* The patch is now flat enough to simply store the corners. */
  276.     
  277.     Node->Node_Type = BEZIER_LEAF_NODE;
  278.     
  279.     Vertices = create_bezier_vertex_block();
  280.     
  281.     Assign_Vector(Vertices->Vertices[0], (*Patch)[0][0]);
  282.     Assign_Vector(Vertices->Vertices[1], (*Patch)[0][3]);
  283.     Assign_Vector(Vertices->Vertices[2], (*Patch)[3][3]);
  284.     Assign_Vector(Vertices->Vertices[3], (*Patch)[3][0]);
  285.     
  286.     Vertices->uvbnds[0] = u0;
  287.     Vertices->uvbnds[1] = u1;
  288.     Vertices->uvbnds[2] = v0;
  289.     Vertices->uvbnds[3] = v1;
  290.  
  291.     Node->Data_Ptr = (void *)Vertices;
  292.   }
  293.   else
  294.   {
  295.     if (depth >= Object->U_Steps)
  296.     {
  297.       if (depth >= Object->V_Steps)
  298.       {
  299.         /* We are at the max recursion depth. Just store corners. */
  300.         
  301.         Node->Node_Type = BEZIER_LEAF_NODE;
  302.         
  303.         Vertices = create_bezier_vertex_block();
  304.         
  305.         Assign_Vector(Vertices->Vertices[0], (*Patch)[0][0]);
  306.         Assign_Vector(Vertices->Vertices[1], (*Patch)[0][3]);
  307.         Assign_Vector(Vertices->Vertices[2], (*Patch)[3][3]);
  308.         Assign_Vector(Vertices->Vertices[3], (*Patch)[3][0]);
  309.         
  310.         Vertices->uvbnds[0] = u0;
  311.         Vertices->uvbnds[1] = u1;
  312.         Vertices->uvbnds[2] = v0;
  313.         Vertices->uvbnds[3] = v1;
  314.         
  315.         Node->Data_Ptr = (void *)Vertices;
  316.       }
  317.       else
  318.       {
  319.         bezier_split_up_down(Patch, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Upper_Left);
  320.         
  321.         Node->Node_Type = BEZIER_INTERIOR_NODE;
  322.         
  323.         Children = create_bezier_child_block();
  324.         
  325.         Children->Children[0] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Lower_Left, u0, u1, v0, (v0 + v1) / 2.0, depth + 1);
  326.         Children->Children[1] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Upper_Left, u0, u1, (v0 + v1) / 2.0, v1, depth + 1);
  327.         
  328.         Node->Count = 2;
  329.         
  330.         Node->Data_Ptr = (void *)Children;
  331.       }
  332.     }
  333.     else
  334.     {
  335.       if (depth >= Object->V_Steps)
  336.       {
  337.         bezier_split_left_right(Patch, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Lower_Right);
  338.         
  339.         Node->Node_Type = BEZIER_INTERIOR_NODE;
  340.         
  341.         Children = create_bezier_child_block();
  342.         
  343.         Children->Children[0] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Lower_Left, u0, (u0 + u1) / 2.0, v0, v1, depth + 1);
  344.         Children->Children[1] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Lower_Right, (u0 + u1) / 2.0, u1, v0, v1, depth + 1);
  345.         
  346.         Node->Count = 2;
  347.         
  348.         Node->Data_Ptr = (void *)Children;
  349.       }
  350.       else
  351.       {
  352.         bezier_split_left_right(Patch, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Lower_Right);
  353.         
  354.         bezier_split_up_down((VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Upper_Left);
  355.         
  356.         bezier_split_up_down((VECTOR(*)[4][4])Lower_Right, (VECTOR(*)[4][4])Lower_Right, (VECTOR(*)[4][4])Upper_Right);
  357.         
  358.         Node->Node_Type = BEZIER_INTERIOR_NODE;
  359.         
  360.         Children = create_bezier_child_block();
  361.         
  362.         Children->Children[0] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Lower_Left, u0, (u0 + u1) / 2.0, v0, (v0 + v1) / 2.0, depth + 1);
  363.         Children->Children[1] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Upper_Left, u0, (u0 + u1) / 2.0, (v0 + v1) / 2.0, v1, depth + 1);
  364.         Children->Children[2] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Lower_Right, (u0 + u1) / 2.0, u1, v0, (v0 + v1) / 2.0, depth + 1);
  365.         Children->Children[3] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Upper_Right, (u0 + u1) / 2.0, u1, (v0 + v1) / 2.0, v1, depth + 1);
  366.         
  367.         Node->Count = 4;
  368.         
  369.         Node->Data_Ptr = (void *)Children;
  370.       }
  371.     }
  372.   }
  373.   
  374.   return (Node);
  375. }
  376.  
  377.  
  378.  
  379. /*****************************************************************************
  380. *
  381. * FUNCTION
  382. *
  383. *   bezier_value
  384. *
  385. * INPUT
  386. *
  387. * OUTPUT
  388. *   
  389. * RETURNS
  390. *   
  391. * AUTHOR
  392. *
  393. *   Alexander Enzmann
  394. *   
  395. * DESCRIPTION
  396. *
  397. *   Determine the position and normal at a single coordinate
  398. *   point (u, v) on a Bezier patch.
  399. *
  400. * CHANGES
  401. *
  402. *   -
  403. *
  404. ******************************************************************************/
  405.  
  406. static void bezier_value(Control_Points, u0, v0, P, N)
  407. VECTOR(*Control_Points)[4][4];
  408. DBL u0, v0;
  409. VECTOR P, N;
  410. {
  411.   int i, j;
  412.   DBL c, t, ut, vt;
  413.   DBL u[4], uu[4], v[4], vv[4];
  414.   DBL du[4], duu[4], dv[4], dvv[4];
  415.   VECTOR U1, V1;
  416.   
  417.   /* Calculate binomial coefficients times coordinate positions. */
  418.   
  419.   u[0] = 1.0; uu[0] = 1.0; du[0] = 0.0; duu[0] = 0.0;
  420.   v[0] = 1.0; vv[0] = 1.0; dv[0] = 0.0; dvv[0] = 0.0;
  421.  
  422.   for (i = 1; i < 4; i++)
  423.   {
  424.     u[i] = u[i - 1] * u0;  uu[i] = uu[i - 1] * (1.0 - u0);
  425.     v[i] = v[i - 1] * v0;  vv[i] = vv[i - 1] * (1.0 - v0);
  426.  
  427.     du[i] = i * u[i - 1];  duu[i] = -i * uu[i - 1];
  428.     dv[i] = i * v[i - 1];  dvv[i] = -i * vv[i - 1];
  429.   }
  430.  
  431.   /* Now evaluate position and tangents based on control points. */
  432.  
  433.   Make_Vector(P, 0, 0, 0);
  434.   Make_Vector(U1, 0, 0, 0);
  435.   Make_Vector(V1, 0, 0, 0);
  436.  
  437.   for (i = 0; i < 4; i++)
  438.   {
  439.     for (j = 0; j < 4; j++)
  440.     {
  441.       c = C[i] * C[j];
  442.       
  443.       ut = u[i] * uu[3 - i];
  444.       vt = v[j] * vv[3 - j];
  445.       
  446.       t = c * ut * vt;
  447.       
  448.       VAddScaledEq(P, t, (*Control_Points)[i][j]);
  449.       
  450.       t = c * vt * (du[i] * uu[3 - i] + u[i] * duu[3 - i]);
  451.       
  452.       VAddScaledEq(U1, t, (*Control_Points)[i][j]);
  453.       
  454.       t = c * ut * (dv[j] * vv[3 - j] + v[j] * dvv[3 - j]);
  455.       
  456.       VAddScaledEq(V1, t, (*Control_Points)[i][j]);
  457.     }
  458.   }
  459.   
  460.   /* Make the normal from the cross product of the tangents. */
  461.   
  462.   VCross(N, U1, V1);
  463.   
  464.   VDot(t, N, N);
  465.   
  466.   if (t > BEZIER_EPSILON)
  467.   {
  468.     t = 1.0 / sqrt(t);
  469.     
  470.     VScaleEq(N, t);
  471.   }
  472.   else
  473.   {
  474.     Make_Vector(N, 1, 0, 0)
  475.   }
  476. }
  477.  
  478.  
  479.  
  480. /*****************************************************************************
  481. *
  482. * FUNCTION
  483. *
  484. *   subpatch_normal
  485. *
  486. * INPUT
  487. *   
  488. * OUTPUT
  489. *   
  490. * RETURNS
  491. *   
  492. * AUTHOR
  493. *
  494. *   Alexander Enzmann
  495. *   
  496. * DESCRIPTION
  497. *
  498. *   Calculate the normal to a subpatch (triangle) return the vector
  499. *   <1.0 0.0 0.0> if the triangle is degenerate.
  500. *
  501. * CHANGES
  502. *
  503. *   -
  504. *
  505. ******************************************************************************/
  506.  
  507. static int subpatch_normal(v1, v2, v3, Result, d)
  508. VECTOR v1, v2, v3, Result;
  509. DBL *d;
  510. {
  511.   VECTOR V1, V2;
  512.   DBL Length;
  513.   
  514.   VSub(V1, v1, v2);
  515.   VSub(V2, v3, v2);
  516.  
  517.   VCross(Result, V1, V2);
  518.  
  519.   VLength(Length, Result);
  520.  
  521.   if (Length < BEZIER_EPSILON)
  522.   {
  523.     Make_Vector(Result, 1.0, 0.0, 0.0);
  524.  
  525.     *d = -1.0 * v1[X];
  526.  
  527.     return (0);
  528.   }
  529.   else
  530.   {
  531.     VInverseScale(Result, Result, Length);
  532.  
  533.     VDot(*d, Result, v1);
  534.  
  535.     *d = 0.0 - *d;
  536.  
  537.     return (1);
  538.   }
  539. }
  540.  
  541.  
  542.  
  543. /*****************************************************************************
  544. *
  545. * FUNCTION
  546. *
  547. *   InvertMatrix
  548. *
  549. * INPUT
  550. *
  551. * OUTPUT
  552. *
  553. * RETURNS
  554. *
  555. * AUTHOR
  556. *
  557. *   Alexander Enzmann
  558. *
  559. * DESCRIPTION
  560. *
  561. *   -
  562. *
  563. * CHANGES
  564. *
  565. *   -
  566. *
  567. ******************************************************************************/
  568.  
  569. static int InvertMatrix(in, out)
  570. VECTOR in[3], out[3];
  571. {
  572.   int i;
  573.   DBL det;
  574.  
  575.   out[0][X] =   (in[1][Y] * in[2][Z] - in[1][Z] * in[2][Y]);
  576.   out[1][X] = - (in[0][Y] * in[2][Z] - in[0][Z] * in[2][Y]);
  577.   out[2][X] =   (in[0][Y] * in[1][Z] - in[0][Z] * in[1][Y]);
  578.  
  579.   out[0][Y] = - (in[1][X] * in[2][Z] - in[1][Z] * in[2][X]);
  580.   out[1][Y] =   (in[0][X] * in[2][Z] - in[0][Z] * in[2][X]);
  581.   out[2][Y] = - (in[0][X] * in[1][Z] - in[0][Z] * in[1][X]);
  582.  
  583.   out[0][Z] =   (in[1][X] * in[2][Y] - in[1][Y] * in[2][X]);
  584.   out[1][Z] = - (in[0][X] * in[2][Y] - in[0][Y] * in[2][X]);
  585.   out[2][Z] =   (in[0][X] * in[1][Y] - in[0][Y] * in[1][X]);
  586.  
  587.   det = in[0][X] * in[1][Y] * in[2][Z] +
  588.         in[0][Y] * in[1][Z] * in[2][X] +
  589.         in[0][Z] * in[1][X] * in[2][Y] -
  590.         in[0][Z] * in[1][Y] * in[2][X] -
  591.         in[0][X] * in[1][Z] * in[2][Y] -
  592.         in[0][Y] * in[1][X] * in[2][Z];
  593.  
  594.   if (fabs(det) < BEZIER_EPSILON)
  595.   {
  596.     return (0);
  597.   }
  598.  
  599.   det = 1.0 / det;
  600.  
  601.   for (i = 0; i < 3; i++)
  602.   {
  603.     VScaleEq(out[i], det)
  604.   }
  605.  
  606.   return (1);
  607. }
  608.  
  609.  
  610.  
  611. /*****************************************************************************
  612. *
  613. * FUNCTION
  614. *
  615. *   intersect_subpatch
  616. *
  617. * INPUT
  618. *
  619. * OUTPUT
  620. *
  621. * RETURNS
  622. *
  623. * AUTHOR
  624. *
  625. *   Alexander Enzmann
  626. *
  627. * DESCRIPTION
  628. *
  629. *   -
  630. *
  631. * CHANGES
  632. *
  633. *   -
  634. *
  635. ******************************************************************************/
  636.  
  637. static int intersect_subpatch(Shape, ray, V1, uu, vv, Depth, P, N, u, v)
  638. BICUBIC_PATCH *Shape;
  639. RAY *ray;
  640. VECTOR V1[3];
  641. DBL uu[3], vv[3], *Depth;
  642. VECTOR P, N;
  643. DBL *u, *v;
  644. {
  645.   DBL d, n, a, b, r;
  646.   VECTOR B[3], IB[3], NN[3], Q, T1;
  647.  
  648.   VSub(B[0], V1[1], V1[0]);
  649.   VSub(B[1], V1[2], V1[0]);
  650.  
  651.   VCross(B[2], B[0], B[1]);
  652.  
  653.   VDot(d, B[2], B[2]);
  654.  
  655.   if (d < BEZIER_EPSILON)
  656.   {
  657.     return (0);
  658.   }
  659.  
  660.   d = 1.0 / sqrt(d);
  661.  
  662.   VScaleEq(B[2], d);
  663.  
  664.   /* Degenerate triangle. */
  665.  
  666.   if (!InvertMatrix(B, IB))
  667.   {
  668.     return (0);
  669.   }
  670.  
  671.   VDot(d, ray->Direction, IB[2]);
  672.  
  673.   if (fabs(d) < BEZIER_EPSILON)
  674.   {
  675.     return (0);
  676.   }
  677.  
  678.   VSub(Q, V1[0], ray->Initial);
  679.  
  680.   VDot(n, Q, IB[2]);
  681.  
  682.   *Depth = n / d;
  683.  
  684.   if (*Depth < BEZIER_TOLERANCE)
  685.   {
  686.     return (0);
  687.   }
  688.  
  689.   VScale(T1, ray->Direction, *Depth);
  690.  
  691.   VAdd(P, ray->Initial, T1);
  692.  
  693.   VSub(Q, P, V1[0]);
  694.  
  695.   VDot(a, Q, IB[0]);
  696.   VDot(b, Q, IB[1]);
  697.  
  698.   if ((a < 0.0) || (b < 0.0) || (a + b > 1.0))
  699.   {
  700.     return (0);
  701.   }
  702.  
  703.   r = 1.0 - a - b;
  704.  
  705.   Make_Vector(N, 0.0, 0.0, 0.0);
  706.  
  707.   bezier_value((VECTOR(*)[4][4])&Shape->Control_Points, uu[0], vv[0], T1, NN[0]);
  708.   bezier_value((VECTOR(*)[4][4])&Shape->Control_Points, uu[1], vv[1], T1, NN[1]);
  709.   bezier_value((VECTOR(*)[4][4])&Shape->Control_Points, uu[2], vv[2], T1, NN[2]);
  710.  
  711.   VScale(T1, NN[0], r); VAddEq(N, T1);
  712.   VScale(T1, NN[1], a); VAddEq(N, T1);
  713.   VScale(T1, NN[2], b); VAddEq(N, T1);
  714.  
  715.   *u = r * uu[0] + a * uu[1] + b * uu[2];
  716.   *v = r * vv[0] + a * vv[1] + b * vv[2];
  717.  
  718.   VDot(d, N, N);
  719.  
  720.   if (d > BEZIER_EPSILON)
  721.   {
  722.     d = 1.0 / sqrt(d);
  723.  
  724.     VScaleEq(N, d);
  725.   }
  726.   else
  727.   {
  728.     Make_Vector(N, 1, 0, 0);
  729.   }
  730.  
  731.   return (1);
  732. }
  733.  
  734.  
  735.  
  736. /*****************************************************************************
  737. *
  738. * FUNCTION
  739. *
  740. *   find_average
  741. *
  742. * INPUT
  743. *
  744. * OUTPUT
  745. *
  746. * RETURNS
  747. *
  748. * AUTHOR
  749. *
  750. *   Alexander Enzmann
  751. *
  752. * DESCRIPTION
  753. *
  754. *   Find a sphere that contains all of the points in the list "vectors".
  755. *
  756. * CHANGES
  757. *
  758. *   -
  759. *
  760. ******************************************************************************/
  761.  
  762. static void find_average(vector_count, vectors, center, radius)
  763. int vector_count;
  764. VECTOR *vectors, center;
  765. DBL *radius;
  766. {
  767.   int i;
  768.   DBL r0, r1, xc = 0, yc = 0, zc = 0;
  769.   DBL x0, y0, z0;
  770.  
  771.   for (i = 0; i < vector_count; i++)
  772.   {
  773.     xc += vectors[i][X];
  774.     yc += vectors[i][Y];
  775.     zc += vectors[i][Z];
  776.   }
  777.  
  778.   xc /= (DBL)vector_count;
  779.   yc /= (DBL)vector_count;
  780.   zc /= (DBL)vector_count;
  781.  
  782.   r0 = 0.0;
  783.  
  784.   for (i = 0; i < vector_count; i++)
  785.   {
  786.     x0 = vectors[i][X] - xc;
  787.     y0 = vectors[i][Y] - yc;
  788.     z0 = vectors[i][Z] - zc;
  789.  
  790.     r1 = x0 * x0 + y0 * y0 + z0 * z0;
  791.  
  792.     if (r1 > r0)
  793.     {
  794.       r0 = r1;
  795.     }
  796.   }
  797.  
  798.   Make_Vector(center, xc, yc, zc);
  799.  
  800.   *radius = r0;
  801. }
  802.  
  803.  
  804.  
  805. /*****************************************************************************
  806. *
  807. * FUNCTION
  808. *
  809. *   spherical_bounds_check
  810. *
  811. * INPUT
  812. *
  813. * OUTPUT
  814. *
  815. * RETURNS
  816. *
  817. * AUTHOR
  818. *
  819. *   Alexander Enzmann
  820. *
  821. * DESCRIPTION
  822. *
  823. *   -
  824. *
  825. * CHANGES
  826. *
  827. *   -
  828. *
  829. ******************************************************************************/
  830.  
  831. static int spherical_bounds_check(Ray, center, radius)
  832. RAY *Ray;
  833. VECTOR center;
  834. DBL radius;
  835. {
  836.   DBL x, y, z, dist1, dist2;
  837.  
  838.   x = center[X] - Ray->Initial[X];
  839.   y = center[Y] - Ray->Initial[Y];
  840.   z = center[Z] - Ray->Initial[Z];
  841.  
  842.   dist1 = x * x + y * y + z * z;
  843.  
  844.   if (dist1 < radius)
  845.   {
  846.     /* ray starts inside sphere - assume it intersects. */
  847.  
  848.     return (1);
  849.   }
  850.   else
  851.   {
  852.     dist2 = x*Ray->Direction[X] + y*Ray->Direction[Y] + z*Ray->Direction[Z];
  853.  
  854.     dist2 *= dist2;
  855.  
  856.     if ((dist2 > 0) && (dist1 - dist2 < radius))
  857.     {
  858.       return (1);
  859.     }
  860.   }
  861.  
  862.   return (0);
  863. }
  864.  
  865.  
  866.  
  867. /*****************************************************************************
  868. *
  869. * FUNCTION
  870. *
  871. *   bezier_bounding_sphere
  872. *
  873. * INPUT
  874. *
  875. * OUTPUT
  876. *
  877. * RETURNS
  878. *
  879. * AUTHOR
  880. *
  881. *   Alexander Enzmann
  882. *
  883. * DESCRIPTION
  884. *
  885. *   Find a sphere that bounds all of the control points of a Bezier patch.
  886. *   The values returned are: the center of the bounding sphere, and the
  887. *   square of the radius of the bounding sphere.
  888. *
  889. * CHANGES
  890. *
  891. *   -
  892. *
  893. ******************************************************************************/
  894.  
  895. static void bezier_bounding_sphere(Patch, center, radius)
  896. VECTOR(*Patch)[4][4], center;
  897. DBL *radius;
  898. {
  899.   int i, j;
  900.   DBL r0, r1, xc = 0, yc = 0, zc = 0;
  901.   DBL x0, y0, z0;
  902.  
  903.   for (i = 0; i < 4; i++)
  904.   {
  905.     for (j = 0; j < 4; j++)
  906.     {
  907.       xc += (*Patch)[i][j][X];
  908.       yc += (*Patch)[i][j][Y];
  909.       zc += (*Patch)[i][j][Z];
  910.     }
  911.   }
  912.  
  913.   xc /= 16.0;
  914.   yc /= 16.0;
  915.   zc /= 16.0;
  916.  
  917.   r0 = 0.0;
  918.  
  919.   for (i = 0; i < 4; i++)
  920.   {
  921.     for (j = 0; j < 4; j++)
  922.     {
  923.       x0 = (*Patch)[i][j][X] - xc;
  924.       y0 = (*Patch)[i][j][Y] - yc;
  925.       z0 = (*Patch)[i][j][Z] - zc;
  926.  
  927.       r1 = x0 * x0 + y0 * y0 + z0 * z0;
  928.  
  929.       if (r1 > r0)
  930.       {
  931.         r0 = r1;
  932.       }
  933.     }
  934.   }
  935.  
  936.   Make_Vector(center, xc, yc, zc);
  937.  
  938.   *radius = r0;
  939. }
  940.  
  941.  
  942.  
  943. /*****************************************************************************
  944. *
  945. * FUNCTION
  946. *
  947. *   Precompute_Patch_Values
  948. *
  949. * INPUT
  950. *
  951. * OUTPUT
  952. *
  953. * RETURNS
  954. *
  955. * AUTHOR
  956. *
  957. *   Alexander Enzmann
  958. *
  959. * DESCRIPTION
  960. *
  961. *   Precompute grid points and normals for a bezier patch.
  962. *
  963. * CHANGES
  964. *
  965. *   -
  966. *
  967. ******************************************************************************/
  968.  
  969. void Precompute_Patch_Values(Shape)
  970. BICUBIC_PATCH *Shape;
  971. {
  972.   int i, j;
  973.   VECTOR Control_Points[16];
  974.   VECTOR(*Patch_Ptr)[4][4] = (VECTOR(*)[4][4]) Shape->Control_Points;
  975.  
  976.   /* Calculate the bounding sphere for the entire patch. */
  977.  
  978.   for (i = 0; i < 4; i++)
  979.   {
  980.     for (j = 0; j < 4; j++)
  981.     {
  982.       Assign_Vector(Control_Points[4*i + j], Shape->Control_Points[i][j]);
  983.     }
  984.   }
  985.  
  986.   find_average(16, Control_Points, Shape->Bounding_Sphere_Center, &Shape->Bounding_Sphere_Radius);
  987.  
  988.   if (Shape->Patch_Type != 0)
  989.   {
  990.     if (Shape->Node_Tree != NULL)
  991.     {
  992.       bezier_tree_deleter(Shape->Node_Tree);
  993.     }
  994.  
  995.     Shape->Node_Tree = bezier_tree_builder(Shape, Patch_Ptr, 0.0, 1.0, 0.0, 1.0, 0);
  996.   }
  997. }
  998.  
  999.  
  1000.  
  1001. /*****************************************************************************
  1002. *
  1003. * FUNCTION
  1004. *
  1005. *   point_plane_distance
  1006. *
  1007. * INPUT
  1008. *
  1009. * OUTPUT
  1010. *
  1011. * RETURNS
  1012. *
  1013. * AUTHOR
  1014. *
  1015. *   Alexander Enzmann
  1016. *
  1017. * DESCRIPTION
  1018. *
  1019. *   Determine the distance from a point to a plane.
  1020. *
  1021. * CHANGES
  1022. *
  1023. *   -
  1024. *
  1025. ******************************************************************************/
  1026.  
  1027. static DBL point_plane_distance(p, n, d)
  1028. VECTOR p, n;
  1029. DBL *d;
  1030. {
  1031.   DBL temp1, temp2;
  1032.  
  1033.   VDot(temp1, p, n);
  1034.  
  1035.   temp1 += *d;
  1036.  
  1037.   VLength(temp2, n);
  1038.  
  1039.   if (fabs(temp2) < EPSILON)
  1040.   {
  1041.     return (0.0);
  1042.   }
  1043.  
  1044.   temp1 /= temp2;
  1045.  
  1046.   return (temp1);
  1047. }
  1048.  
  1049.  
  1050.  
  1051. /*****************************************************************************
  1052. *
  1053. * FUNCTION
  1054. *
  1055. *   bezier_subpatch_intersect
  1056. *
  1057. * INPUT
  1058. *
  1059. * OUTPUT
  1060. *
  1061. * RETURNS
  1062. *
  1063. * AUTHOR
  1064. *
  1065. *   Alexander Enzmann
  1066. *
  1067. * DESCRIPTION
  1068. *
  1069. *   -
  1070. *
  1071. * CHANGES
  1072. *
  1073. *   -
  1074. *
  1075. ******************************************************************************/
  1076.  
  1077. static int bezier_subpatch_intersect(ray, Shape, Patch, u0, u1, v0, v1, Depth_Stack)
  1078. RAY *ray;
  1079. BICUBIC_PATCH *Shape;
  1080. VECTOR(*Patch)[4][4];
  1081. DBL u0, u1, v0, v1;
  1082. ISTACK *Depth_Stack;
  1083. {
  1084.   int cnt = 0;
  1085.   VECTOR V1[3];
  1086.   DBL u, v, Depth, uu[3], vv[3];
  1087.   VECTOR P, N;
  1088.  
  1089.   Assign_Vector(V1[0], (*Patch)[0][0]);
  1090.   Assign_Vector(V1[1], (*Patch)[0][3]);
  1091.   Assign_Vector(V1[2], (*Patch)[3][3]);
  1092.  
  1093.   uu[0] = u0; uu[1] = u0; uu[2] = u1;
  1094.   vv[0] = v0; vv[1] = v1; vv[2] = v1;
  1095.  
  1096.   if (intersect_subpatch(Shape, ray, V1, uu, vv, &Depth, P, N, &u, &v))
  1097.   {
  1098.     push_normal_entry(Depth, P, N, (OBJECT *)Shape, Depth_Stack);
  1099.  
  1100.     cnt++;
  1101.   }
  1102.  
  1103.   Assign_Vector(V1[1], V1[2]);
  1104.   Assign_Vector(V1[2], (*Patch)[3][0]);
  1105.  
  1106.   uu[1] = uu[2]; uu[2] = u1;
  1107.   vv[1] = vv[2]; vv[2] = v0;
  1108.  
  1109.   if (intersect_subpatch(Shape, ray, V1, uu, vv, &Depth, P, N, &u, &v))
  1110.   {
  1111.     push_normal_entry(Depth, P, N, (OBJECT *)Shape, Depth_Stack);
  1112.  
  1113.     cnt++;
  1114.   }
  1115.  
  1116.   return (cnt);
  1117. }
  1118.  
  1119.  
  1120.  
  1121.  
  1122. /*****************************************************************************
  1123. *
  1124. * FUNCTION
  1125. *
  1126. *   bezier_split_left_right
  1127. *
  1128. * INPUT
  1129. *
  1130. * OUTPUT
  1131. *
  1132. * RETURNS
  1133. *
  1134. * AUTHOR
  1135. *
  1136. *   Alexander Enzmann
  1137. *
  1138. * DESCRIPTION
  1139. *
  1140. *   -
  1141. *
  1142. * CHANGES
  1143. *
  1144. *   -
  1145. *
  1146. ******************************************************************************/
  1147.  
  1148. static void bezier_split_left_right(Patch, Left_Patch, Right_Patch)
  1149. VECTOR(*Patch)[4][4], (*Left_Patch)[4][4], (*Right_Patch)[4][4];
  1150. {
  1151.   int i, j;
  1152.   VECTOR Temp1[4], Temp2[4], Half;
  1153.  
  1154.   for (i = 0; i < 4; i++)
  1155.   {
  1156.     Assign_Vector(Temp1[0], (*Patch)[0][i]);
  1157.  
  1158.     VHalf(Temp1[1], (*Patch)[0][i], (*Patch)[1][i]);
  1159.     VHalf(Half, (*Patch)[1][i], (*Patch)[2][i]);
  1160.     VHalf(Temp1[2], Temp1[1], Half);
  1161.     VHalf(Temp2[2], (*Patch)[2][i], (*Patch)[3][i]);
  1162.     VHalf(Temp2[1], Half, Temp2[2]);
  1163.     VHalf(Temp1[3], Temp1[2], Temp2[1]);
  1164.  
  1165.     Assign_Vector(Temp2[0], Temp1[3]);
  1166.     Assign_Vector(Temp2[3], (*Patch)[3][i]);
  1167.  
  1168.     for (j = 0; j < 4; j++)
  1169.     {
  1170.       Assign_Vector((*Left_Patch)[j][i], Temp1[j]);
  1171.       Assign_Vector((*Right_Patch)[j][i], Temp2[j]);
  1172.     }
  1173.   }
  1174. }
  1175.  
  1176.  
  1177.  
  1178. /*****************************************************************************
  1179. *
  1180. * FUNCTION
  1181. *
  1182. *   bezier_split_up_down
  1183. *
  1184. * INPUT
  1185. *
  1186. * OUTPUT
  1187. *
  1188. * RETURNS
  1189. *
  1190. * AUTHOR
  1191. *
  1192. *   Alexander Enzmann
  1193. *
  1194. * DESCRIPTION
  1195. *
  1196. *   -
  1197. *
  1198. * CHANGES
  1199. *
  1200. *   -
  1201. *
  1202. ******************************************************************************/
  1203.  
  1204. static void bezier_split_up_down(Patch, Bottom_Patch, Top_Patch)
  1205. VECTOR(*Patch)[4][4], (*Top_Patch)[4][4], (*Bottom_Patch)[4][4];
  1206. {
  1207.   int i, j;
  1208.   VECTOR Temp1[4], Temp2[4], Half;
  1209.  
  1210.   for (i = 0; i < 4; i++)
  1211.   {
  1212.     Assign_Vector(Temp1[0], (*Patch)[i][0]);
  1213.  
  1214.     VHalf(Temp1[1], (*Patch)[i][0], (*Patch)[i][1]);
  1215.     VHalf(Half, (*Patch)[i][1], (*Patch)[i][2]);
  1216.     VHalf(Temp1[2], Temp1[1], Half);
  1217.     VHalf(Temp2[2], (*Patch)[i][2], (*Patch)[i][3]);
  1218.     VHalf(Temp2[1], Half, Temp2[2]);
  1219.     VHalf(Temp1[3], Temp1[2], Temp2[1]);
  1220.  
  1221.     Assign_Vector(Temp2[0], Temp1[3]);
  1222.     Assign_Vector(Temp2[3], (*Patch)[i][3]);
  1223.  
  1224.     for (j = 0; j < 4; j++)
  1225.     {
  1226.       Assign_Vector((*Bottom_Patch)[i][j], Temp1[j]);
  1227.       Assign_Vector((*Top_Patch)[i][j]   , Temp2[j]);
  1228.     }
  1229.   }
  1230. }
  1231.  
  1232.  
  1233.  
  1234. /*****************************************************************************
  1235. *
  1236. * FUNCTION
  1237. *
  1238. *   determine_subpatch_flatness
  1239. *
  1240. * INPUT
  1241. *
  1242. * OUTPUT
  1243. *
  1244. * RETURNS
  1245. *
  1246. * AUTHOR
  1247. *
  1248. *   Alexander Enzmann
  1249. *
  1250. * DESCRIPTION
  1251. *
  1252. *   See how close to a plane a subpatch is, the patch must have at least
  1253. *   three distinct vertices. A negative result from this function indicates
  1254. *   that a degenerate value of some sort was encountered.
  1255. *
  1256. * CHANGES
  1257. *
  1258. *   -
  1259. *
  1260. ******************************************************************************/
  1261.  
  1262. static DBL determine_subpatch_flatness(Patch)
  1263. VECTOR(*Patch)[4][4];
  1264. {
  1265.   int i, j;
  1266.   DBL d, dist, temp1;
  1267.   VECTOR vertices[4], n, TempV;
  1268.  
  1269.   Assign_Vector(vertices[0], (*Patch)[0][0]);
  1270.   Assign_Vector(vertices[1], (*Patch)[0][3]);
  1271.  
  1272.   VSub(TempV, vertices[0], vertices[1]);
  1273.  
  1274.   VLength(temp1, TempV);
  1275.  
  1276.   if (fabs(temp1) < EPSILON)
  1277.   {
  1278.     /*
  1279.      * Degenerate in the V direction for U = 0. This is ok if the other
  1280.      * two corners are distinct from the lower left corner - I'm sure there
  1281.      * are cases where the corners coincide and the middle has good values,
  1282.      * but that is somewhat pathalogical and won't be considered.
  1283.      */
  1284.  
  1285.     Assign_Vector(vertices[1], (*Patch)[3][3]);
  1286.  
  1287.     VSub(TempV, vertices[0], vertices[1]);
  1288.  
  1289.     VLength(temp1, TempV);
  1290.  
  1291.     if (fabs(temp1) < EPSILON)
  1292.     {
  1293.       return (-1.0);
  1294.     }
  1295.  
  1296.     Assign_Vector(vertices[2], (*Patch)[3][0]);
  1297.  
  1298.     VSub(TempV, vertices[0], vertices[1]);
  1299.  
  1300.     VLength(temp1, TempV);
  1301.  
  1302.     if (fabs(temp1) < EPSILON)
  1303.     {
  1304.       return (-1.0);
  1305.     }
  1306.  
  1307.     VSub(TempV, vertices[1], vertices[2]);
  1308.  
  1309.     VLength(temp1, TempV);
  1310.  
  1311.     if (fabs(temp1) < EPSILON)
  1312.     {
  1313.       return (-1.0);
  1314.     }
  1315.   }
  1316.   else
  1317.   {
  1318.     Assign_Vector(vertices[2], (*Patch)[3][0]);
  1319.  
  1320.     VSub(TempV, vertices[0], vertices[1]);
  1321.  
  1322.     VLength(temp1, TempV);
  1323.  
  1324.     if (fabs(temp1) < EPSILON)
  1325.     {
  1326.       Assign_Vector(vertices[2], (*Patch)[3][3]);
  1327.  
  1328.       VSub(TempV, vertices[0], vertices[2]);
  1329.  
  1330.       VLength(temp1, TempV);
  1331.  
  1332.       if (fabs(temp1) < EPSILON)
  1333.       {
  1334.         return (-1.0);
  1335.       }
  1336.  
  1337.       VSub(TempV, vertices[1], vertices[2]);
  1338.  
  1339.       VLength(temp1, TempV);
  1340.  
  1341.       if (fabs(temp1) < EPSILON)
  1342.       {
  1343.         return (-1.0);
  1344.       }
  1345.     }
  1346.     else
  1347.     {
  1348.       VSub(TempV, vertices[1], vertices[2]);
  1349.  
  1350.       VLength(temp1, TempV);
  1351.  
  1352.       if (fabs(temp1) < EPSILON)
  1353.       {
  1354.         return (-1.0);
  1355.       }
  1356.     }
  1357.   }
  1358.  
  1359.   /*
  1360.    * Now that a good set of candidate points has been found,
  1361.    * find the plane equations for the patch.
  1362.    */
  1363.  
  1364.   if (subpatch_normal(vertices[0], vertices[1], vertices[2], n, &d))
  1365.   {
  1366.     /*
  1367.      * Step through all vertices and see what the maximum
  1368.      * distance from the plane happens to be.
  1369.      */
  1370.  
  1371.     dist = 0.0;
  1372.  
  1373.     for (i = 0; i < 4; i++)
  1374.     {
  1375.       for (j = 0; j < 4; j++)
  1376.       {
  1377.         temp1 = fabs(point_plane_distance(((*Patch)[i][j]), n, &d));
  1378.  
  1379.         if (temp1 > dist)
  1380.         {
  1381.           dist = temp1;
  1382.         }
  1383.       }
  1384.     }
  1385.  
  1386.     return (dist);
  1387.   }
  1388.   else
  1389.   {
  1390. /*
  1391.     Debug_Info("Subpatch normal failed in determine_subpatch_flatness\n");
  1392. */
  1393.  
  1394.     return (-1.0);
  1395.   }
  1396. }
  1397.  
  1398.  
  1399.  
  1400. /*****************************************************************************
  1401. *
  1402. * FUNCTION
  1403. *
  1404. *   flat_enough
  1405. *
  1406. * INPUT
  1407. *
  1408. * OUTPUT
  1409. *
  1410. * RETURNS
  1411. *
  1412. * AUTHOR
  1413. *
  1414. *   Alexander Enzmann
  1415. *
  1416. * DESCRIPTION
  1417. *
  1418. *   -
  1419. *
  1420. * CHANGES
  1421. *
  1422. *   -
  1423. *
  1424. ******************************************************************************/
  1425.  
  1426. static int flat_enough(Object, Patch)
  1427. BICUBIC_PATCH *Object;
  1428. VECTOR(*Patch)[4][4];
  1429. {
  1430.   DBL Dist;
  1431.  
  1432.   Dist = determine_subpatch_flatness(Patch);
  1433.  
  1434.   if (Dist < 0.0)
  1435.   {
  1436.     return (0);
  1437.   }
  1438.   else
  1439.   {
  1440.     if (Dist < Object->Flatness_Value)
  1441.     {
  1442.       return (1);
  1443.     }
  1444.     else
  1445.     {
  1446.       return (0);
  1447.     }
  1448.   }
  1449. }
  1450.  
  1451.  
  1452.  
  1453. /*****************************************************************************
  1454. *
  1455. * FUNCTION
  1456. *
  1457. *   bezier_subdivider
  1458. *
  1459. * INPUT
  1460. *
  1461. * OUTPUT
  1462. *
  1463. * RETURNS
  1464. *
  1465. * AUTHOR
  1466. *
  1467. *   Alexander Enzmann
  1468. *
  1469. * DESCRIPTION
  1470. *
  1471. *   -
  1472. *
  1473. * CHANGES
  1474. *
  1475. *   -
  1476. *
  1477. ******************************************************************************/
  1478.  
  1479. static int bezier_subdivider(Ray, Object, Patch, u0, u1, v0, v1,
  1480. recursion_depth, Depth_Stack)
  1481. RAY *Ray;
  1482. BICUBIC_PATCH *Object;
  1483. VECTOR(*Patch)[4][4];
  1484. DBL u0, u1, v0, v1;
  1485. int recursion_depth;
  1486. ISTACK *Depth_Stack;
  1487. {
  1488.   int cnt = 0;
  1489.   DBL ut, vt, radius;
  1490.   VECTOR Lower_Left[4][4], Lower_Right[4][4];
  1491.   VECTOR Upper_Left[4][4], Upper_Right[4][4];
  1492.   VECTOR center;
  1493.  
  1494.   /*
  1495.    * Make sure the ray passes through a sphere bounding
  1496.    * the control points of the patch.
  1497.    */
  1498.  
  1499.   bezier_bounding_sphere(Patch, center, &radius);
  1500.  
  1501.   if (!spherical_bounds_check(Ray, center, radius))
  1502.   {
  1503.     return (0);
  1504.   }
  1505.  
  1506.   /*
  1507.    * If the patch is close to being flat, then just
  1508.    * perform a ray-plane intersection test.
  1509.    */
  1510.  
  1511.   if (flat_enough(Object, Patch))
  1512.   {
  1513.     return bezier_subpatch_intersect(Ray, Object, Patch, u0, u1, v0, v1, Depth_Stack);
  1514.   }
  1515.  
  1516.   if (recursion_depth >= Object->U_Steps)
  1517.   {
  1518.     if (recursion_depth >= Object->V_Steps)
  1519.     {
  1520.       return bezier_subpatch_intersect(Ray, Object, Patch, u0, u1, v0, v1, Depth_Stack);
  1521.     }
  1522.     else
  1523.     {
  1524.       bezier_split_up_down(Patch, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Upper_Left);
  1525.  
  1526.       vt = (v1 - v0) / 2.0;
  1527.  
  1528.       cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Lower_Left, u0, u1, v0, vt, recursion_depth + 1, Depth_Stack);
  1529.       cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Upper_Left, u0, u1, vt, v1, recursion_depth + 1, Depth_Stack);
  1530.     }
  1531.   }
  1532.   else
  1533.   {
  1534.     if (recursion_depth >= Object->V_Steps)
  1535.     {
  1536.       bezier_split_left_right(Patch, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Lower_Right);
  1537.  
  1538.       ut = (u1 - u0) / 2.0;
  1539.  
  1540.       cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Lower_Left, u0, ut, v0, v1, recursion_depth + 1, Depth_Stack);
  1541.       cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Lower_Right, ut, u1, v0, v1, recursion_depth + 1, Depth_Stack);
  1542.     }
  1543.     else
  1544.     {
  1545.       ut = (u1 - u0) / 2.0;
  1546.       vt = (v1 - v0) / 2.0;
  1547.  
  1548.       bezier_split_left_right(Patch, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Lower_Right);
  1549.       bezier_split_up_down((VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Upper_Left) ;
  1550.       bezier_split_up_down((VECTOR(*)[4][4])Lower_Right, (VECTOR(*)[4][4])Lower_Right, (VECTOR(*)[4][4])Upper_Right);
  1551.  
  1552.       cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Lower_Left, u0, ut, v0, vt, recursion_depth + 1, Depth_Stack);
  1553.       cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Upper_Left, u0, ut, vt, v1, recursion_depth + 1, Depth_Stack);
  1554.       cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Lower_Right, ut, u1, v0, vt, recursion_depth + 1, Depth_Stack);
  1555.       cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Upper_Right, ut, u1, vt, v1, recursion_depth + 1, Depth_Stack);
  1556.     }
  1557.   }
  1558.  
  1559.   return (cnt);
  1560. }
  1561.  
  1562.  
  1563.  
  1564. /*****************************************************************************
  1565. *
  1566. * FUNCTION
  1567. *
  1568. *   bezier_tree_deleter
  1569. *
  1570. * INPUT
  1571. *
  1572. * OUTPUT
  1573. *
  1574. * RETURNS
  1575. *
  1576. * AUTHOR
  1577. *
  1578. *   Alexander Enzmann
  1579. *
  1580. * DESCRIPTION
  1581. *
  1582. *   -
  1583. *
  1584. * CHANGES
  1585. *
  1586. *   -
  1587. *
  1588. ******************************************************************************/
  1589.  
  1590. static void bezier_tree_deleter(Node)
  1591. BEZIER_NODE *Node;
  1592. {
  1593.   int i;
  1594.   BEZIER_CHILDREN *Children;
  1595.  
  1596.   /* If this is an interior node then continue the descent. */
  1597.  
  1598.   if (Node->Node_Type == BEZIER_INTERIOR_NODE)
  1599.   {
  1600.     Children = (BEZIER_CHILDREN *)Node->Data_Ptr;
  1601.  
  1602.     for (i = 0; i < Node->Count; i++)
  1603.     {
  1604.       bezier_tree_deleter(Children->Children[i]);
  1605.     }
  1606.  
  1607.     POV_FREE(Children);
  1608.   }
  1609.   else
  1610.   {
  1611.     if (Node->Node_Type == BEZIER_LEAF_NODE)
  1612.     {
  1613.       /* Free the memory used for the vertices. */
  1614.  
  1615.       POV_FREE(Node->Data_Ptr);
  1616.     }
  1617.   }
  1618.  
  1619.   /* Free the memory used for the node. */
  1620.  
  1621.   POV_FREE(Node);
  1622. }
  1623.  
  1624.  
  1625.  
  1626. /*****************************************************************************
  1627. *
  1628. * FUNCTION
  1629. *
  1630. *   bezier_tree_walker
  1631. *
  1632. * INPUT
  1633. *
  1634. * OUTPUT
  1635. *
  1636. * RETURNS
  1637. *
  1638. * AUTHOR
  1639. *
  1640. *   Alexander Enzmann
  1641. *
  1642. * DESCRIPTION
  1643. *
  1644. *   -
  1645. *
  1646. * CHANGES
  1647. *
  1648. *   -
  1649. *
  1650. ******************************************************************************/
  1651.  
  1652. static int bezier_tree_walker(Ray, Shape, Node, Depth_Stack)
  1653. RAY *Ray;
  1654. BICUBIC_PATCH *Shape;
  1655. BEZIER_NODE *Node;
  1656. ISTACK *Depth_Stack;
  1657. {
  1658.   int i, cnt = 0;
  1659.   DBL Depth, u, v, uu[3], vv[3];
  1660.   VECTOR N, P, V1[3];
  1661.   BEZIER_CHILDREN *Children;
  1662.   BEZIER_VERTICES *Vertices;
  1663.  
  1664.   /*
  1665.    * Make sure the ray passes through a sphere bounding
  1666.    * the control points of the patch.
  1667.    */
  1668.  
  1669.   if (!spherical_bounds_check(Ray, Node->Center, Node->Radius_Squared))
  1670.   {
  1671.     return (0);
  1672.   }
  1673.  
  1674.   /*
  1675.    * If this is an interior node then continue the descent,
  1676.    * else do a check against the vertices.
  1677.    */
  1678.  
  1679.   if (Node->Node_Type == BEZIER_INTERIOR_NODE)
  1680.   {
  1681.     Children = (BEZIER_CHILDREN *)Node->Data_Ptr;
  1682.  
  1683.     for (i = 0; i < Node->Count; i++)
  1684.     {
  1685.       cnt += bezier_tree_walker(Ray, Shape, Children->Children[i], Depth_Stack);
  1686.     }
  1687.   }
  1688.   else if (Node->Node_Type == BEZIER_LEAF_NODE)
  1689.   {
  1690.     Vertices = (BEZIER_VERTICES *)Node->Data_Ptr;
  1691.  
  1692.     Assign_Vector(V1[0], Vertices->Vertices[0]);
  1693.     Assign_Vector(V1[1], Vertices->Vertices[1]);
  1694.     Assign_Vector(V1[2], Vertices->Vertices[2]);
  1695.  
  1696.     uu[0] = Vertices->uvbnds[0];
  1697.     uu[1] = Vertices->uvbnds[0];
  1698.     uu[2] = Vertices->uvbnds[1];
  1699.     vv[0] = Vertices->uvbnds[2];
  1700.     vv[1] = Vertices->uvbnds[3];
  1701.     vv[2] = Vertices->uvbnds[3];
  1702.  
  1703.     /*
  1704.      * Triangulate this subpatch, then check for
  1705.      * intersections in the triangles.
  1706.      */
  1707.  
  1708.     if (intersect_subpatch(Shape, Ray, V1, uu, vv, &Depth, P, N, &u, &v))
  1709.     {
  1710.       push_normal_entry(Depth, P, N, (OBJECT *)Shape, Depth_Stack);
  1711.  
  1712.       cnt++;
  1713.     }
  1714.  
  1715.     Assign_Vector(V1[1], V1[2]);
  1716.     Assign_Vector(V1[2], Vertices->Vertices[3]);
  1717.  
  1718.     uu[1] = uu[2]; uu[2] = Vertices->uvbnds[1];
  1719.     vv[1] = vv[2]; vv[2] = Vertices->uvbnds[2];
  1720.  
  1721.     if (intersect_subpatch(Shape, Ray, V1, uu, vv, &Depth, P, N, &u, &v))
  1722.     {
  1723.       push_normal_entry(Depth, P, N, (OBJECT *)Shape, Depth_Stack);
  1724.  
  1725.       cnt++;
  1726.     }
  1727.   }
  1728.   else
  1729.   {
  1730.     Error("Bad Node type in bezier_tree_walker().\n");
  1731.   }
  1732.  
  1733.   return (cnt);
  1734. }
  1735.  
  1736.  
  1737.  
  1738. /*****************************************************************************
  1739. *
  1740. * FUNCTION
  1741. *
  1742. *   intersect_bicubic_patch0
  1743. *
  1744. * INPUT
  1745. *
  1746. * OUTPUT
  1747. *
  1748. * RETURNS
  1749. *
  1750. * AUTHOR
  1751. *
  1752. *   Alexander Enzmann
  1753. *
  1754. * DESCRIPTION
  1755. *
  1756. *   -
  1757. *
  1758. * CHANGES
  1759. *
  1760. *   -
  1761. *
  1762. ******************************************************************************/
  1763.  
  1764. static int intersect_bicubic_patch0(Ray, Shape, Depth_Stack)
  1765. RAY *Ray;
  1766. BICUBIC_PATCH *Shape;
  1767. ISTACK *Depth_Stack;
  1768. {
  1769.   VECTOR(*Patch)[4][4] = (VECTOR(*)[4][4]) Shape->Control_Points;
  1770.   
  1771.   return (bezier_subdivider(Ray, Shape, Patch, 0.0, 1.0, 0.0, 1.0, 0, Depth_Stack));
  1772. }
  1773.  
  1774.  
  1775.  
  1776. /*****************************************************************************
  1777. *
  1778. * FUNCTION
  1779. *
  1780. *   All_Bicubic_Patch_Intersections
  1781. *
  1782. * INPUT
  1783. *   
  1784. * OUTPUT
  1785. *   
  1786. * RETURNS
  1787. *   
  1788. * AUTHOR
  1789. *
  1790. *   Alexander Enzmann
  1791. *   
  1792. * DESCRIPTION
  1793. *
  1794. *   -
  1795. *
  1796. * CHANGES
  1797. *
  1798. *   -
  1799. *
  1800. ******************************************************************************/
  1801.  
  1802. static int All_Bicubic_Patch_Intersections(Object, Ray, Depth_Stack)
  1803. OBJECT *Object;
  1804. RAY *Ray;
  1805. ISTACK *Depth_Stack;
  1806. {
  1807.   int Found, cnt = 0;
  1808.  
  1809.   Found = FALSE;
  1810.  
  1811.   Increase_Counter(stats[Ray_Bicubic_Tests]);
  1812.  
  1813.   switch (((BICUBIC_PATCH *)Object)->Patch_Type)
  1814.   {
  1815.     case 0:
  1816.  
  1817.       cnt = intersect_bicubic_patch0(Ray, ((BICUBIC_PATCH *)Object), Depth_Stack);
  1818.  
  1819.       break;
  1820.  
  1821.     case 1:
  1822.  
  1823.       cnt = bezier_tree_walker(Ray, (BICUBIC_PATCH *)Object, ((BICUBIC_PATCH *)Object)->Node_Tree, Depth_Stack);
  1824.  
  1825.       break;
  1826.  
  1827.     default:
  1828.  
  1829.       Error("Bad patch type in All_Bicubic_Patch_Intersections.\n");
  1830.   }
  1831.   
  1832.   if (cnt > 0)
  1833.   {
  1834.     Increase_Counter(stats[Ray_Bicubic_Tests_Succeeded]);
  1835.     
  1836.     Found = TRUE;
  1837.   }
  1838.   
  1839.   return (Found);
  1840. }
  1841.  
  1842.  
  1843.  
  1844. /*****************************************************************************
  1845. *
  1846. * FUNCTION
  1847. *
  1848. *   Inside_Bicubic_Patch
  1849. *
  1850. * INPUT
  1851. *   
  1852. * OUTPUT
  1853. *   
  1854. * RETURNS
  1855. *   
  1856. * AUTHOR
  1857. *
  1858. *   Alexander Enzmann
  1859. *   
  1860. * DESCRIPTION
  1861. *
  1862. *   A patch is not a solid, so an inside test doesn't make sense.
  1863. *
  1864. * CHANGES
  1865. *
  1866. *   -
  1867. *
  1868. ******************************************************************************/
  1869.  
  1870. static int Inside_Bicubic_Patch(IPoint, Object)
  1871. VECTOR IPoint;
  1872. OBJECT *Object;
  1873. {
  1874.   return (0);
  1875. }
  1876.  
  1877.  
  1878.  
  1879. /*****************************************************************************
  1880. *
  1881. * FUNCTION
  1882. *
  1883. *   Bicubic_Patch_Normal
  1884. *
  1885. * INPUT
  1886. *   
  1887. * OUTPUT
  1888. *   
  1889. * RETURNS
  1890. *   
  1891. * AUTHOR
  1892. *
  1893. *   Alexander Enzmann
  1894. *   
  1895. * DESCRIPTION
  1896. *
  1897. *   -
  1898. *
  1899. * CHANGES
  1900. *
  1901. *   -
  1902. *
  1903. ******************************************************************************/
  1904.  
  1905. static void Bicubic_Patch_Normal(Result, Object, Inter)
  1906. OBJECT *Object;
  1907. VECTOR Result;
  1908. INTERSECTION *Inter;
  1909. {
  1910.   /* Use preocmputed normal. */
  1911.  
  1912.   Assign_Vector(Result, Inter->INormal);
  1913. }
  1914.  
  1915.  
  1916.  
  1917. /*****************************************************************************
  1918. *
  1919. * FUNCTION
  1920. *
  1921. *   Translate_Bicubic_Patch
  1922. *
  1923. * INPUT
  1924. *   
  1925. * OUTPUT
  1926. *   
  1927. * RETURNS
  1928. *   
  1929. * AUTHOR
  1930. *
  1931. *   Alexander Enzmann
  1932. *   
  1933. * DESCRIPTION
  1934. *
  1935. *   -
  1936. *
  1937. * CHANGES
  1938. *
  1939. *   -
  1940. *
  1941. ******************************************************************************/
  1942.  
  1943. static void Translate_Bicubic_Patch(Object, Vector, Trans)
  1944. OBJECT *Object;
  1945. VECTOR Vector;
  1946. TRANSFORM *Trans;
  1947. {
  1948.   int i, j;
  1949.   BICUBIC_PATCH *Patch = (BICUBIC_PATCH *) Object;
  1950.  
  1951.   for (i = 0; i < 4; i++)
  1952.   {
  1953.     for (j = 0; j < 4; j++)
  1954.     {
  1955.       VAdd(Patch->Control_Points[i][j], Patch->Control_Points[i][j], Vector)
  1956.     }
  1957.   }
  1958.  
  1959.   Precompute_Patch_Values(Patch);
  1960.  
  1961.   Compute_Bicubic_Patch_BBox(Patch);
  1962. }
  1963.  
  1964.  
  1965.  
  1966. /*****************************************************************************
  1967. *
  1968. * FUNCTION
  1969. *
  1970. *   Rotate_Bicubic_Patch
  1971. *
  1972. * INPUT
  1973. *   
  1974. * OUTPUT
  1975. *   
  1976. * RETURNS
  1977. *   
  1978. * AUTHOR
  1979. *
  1980. *   Alexander Enzmann
  1981. *   
  1982. * DESCRIPTION
  1983. *
  1984. *   -
  1985. *
  1986. * CHANGES
  1987. *
  1988. *   -
  1989. *
  1990. ******************************************************************************/
  1991.  
  1992. static void Rotate_Bicubic_Patch(Object, Vector, Trans)
  1993. OBJECT *Object;
  1994. VECTOR Vector;
  1995. TRANSFORM *Trans;
  1996. {
  1997.   Transform_Bicubic_Patch(Object, Trans);
  1998. }
  1999.  
  2000.  
  2001.  
  2002. /*****************************************************************************
  2003. *
  2004. * FUNCTION
  2005. *
  2006. *   Scale_Bicubic_Patch
  2007. *
  2008. * INPUT
  2009. *   
  2010. * OUTPUT
  2011. *   
  2012. * RETURNS
  2013. *   
  2014. * AUTHOR
  2015. *
  2016. *   Alexander Enzmann
  2017. *   
  2018. * DESCRIPTION
  2019. *
  2020. *   -
  2021. *
  2022. * CHANGES
  2023. *
  2024. *   -
  2025. *
  2026. ******************************************************************************/
  2027.  
  2028. static void Scale_Bicubic_Patch(Object, Vector, Trans)
  2029. OBJECT *Object;
  2030. VECTOR Vector;
  2031. TRANSFORM *Trans;
  2032. {
  2033.   int i, j;
  2034.   BICUBIC_PATCH *Patch = (BICUBIC_PATCH *) Object;
  2035.  
  2036.   for (i = 0; i < 4; i++)
  2037.   {
  2038.     for (j = 0; j < 4; j++)
  2039.     {
  2040.       VEvaluate(Patch->Control_Points[i][j], Patch->Control_Points[i][j], Vector);
  2041.     }
  2042.   }
  2043.  
  2044.   Precompute_Patch_Values(Patch);
  2045.  
  2046.   Compute_Bicubic_Patch_BBox(Patch);
  2047. }
  2048.  
  2049.  
  2050.  
  2051.  
  2052. /*****************************************************************************
  2053. *
  2054. * FUNCTION
  2055. *
  2056. *   Transform_Bicubic_Patch
  2057. *
  2058. * INPUT
  2059. *   
  2060. * OUTPUT
  2061. *   
  2062. * RETURNS
  2063. *   
  2064. * AUTHOR
  2065. *
  2066. *   Alexander Enzmann
  2067. *   
  2068. * DESCRIPTION
  2069. *
  2070. *   -
  2071. *
  2072. * CHANGES
  2073. *
  2074. *   -
  2075. *
  2076. ******************************************************************************/
  2077.  
  2078. static void Transform_Bicubic_Patch(Object, Trans)
  2079. OBJECT *Object;
  2080. TRANSFORM *Trans;
  2081. {
  2082.   int i, j;
  2083.   BICUBIC_PATCH *Patch = (BICUBIC_PATCH *) Object;
  2084.   
  2085.   for (i = 0; i < 4; i++)
  2086.   {
  2087.     for (j = 0; j < 4; j++)
  2088.     {
  2089.       MTransPoint(Patch->Control_Points[i][j], Patch->Control_Points[i][j], Trans);
  2090.     }
  2091.   }
  2092.   
  2093.   Precompute_Patch_Values(Patch);
  2094.   
  2095.   Compute_Bicubic_Patch_BBox(Patch);
  2096. }
  2097.  
  2098.  
  2099.  
  2100. /*****************************************************************************
  2101. *
  2102. * FUNCTION
  2103. *
  2104. *   Invert_Bicubic_Patch
  2105. *
  2106. * INPUT
  2107. *   
  2108. * OUTPUT
  2109. *   
  2110. * RETURNS
  2111. *   
  2112. * AUTHOR
  2113. *
  2114. *   Alexander Enzmann
  2115. *   
  2116. * DESCRIPTION
  2117. *
  2118. *   Inversion of a patch really doesn't make sense.
  2119. *
  2120. * CHANGES
  2121. *
  2122. *   -
  2123. *
  2124. ******************************************************************************/
  2125.  
  2126. static void Invert_Bicubic_Patch(Object)
  2127. OBJECT *Object;
  2128. {
  2129. }
  2130.  
  2131.  
  2132.  
  2133. /*****************************************************************************
  2134. *
  2135. * FUNCTION
  2136. *
  2137. *   Create_Bicubic_Patch
  2138. *
  2139. * INPUT
  2140. *   
  2141. * OUTPUT
  2142. *   
  2143. * RETURNS
  2144. *   
  2145. * AUTHOR
  2146. *
  2147. *   Alexander Enzmann
  2148. *   
  2149. * DESCRIPTION
  2150. *
  2151. *   -
  2152. *
  2153. * CHANGES
  2154. *
  2155. *   -
  2156. *
  2157. ******************************************************************************/
  2158.  
  2159. BICUBIC_PATCH *Create_Bicubic_Patch()
  2160. {
  2161.   BICUBIC_PATCH *New;
  2162.   
  2163.   New = (BICUBIC_PATCH *)POV_MALLOC(sizeof (BICUBIC_PATCH), "bicubic patch");
  2164.   
  2165.   INIT_OBJECT_FIELDS(New, BICUBIC_PATCH_OBJECT, &Bicubic_Patch_Methods)
  2166.     
  2167.     New->Patch_Type = - 1;
  2168.   
  2169.   New->U_Steps = 0;
  2170.   New->V_Steps = 0;
  2171.   
  2172.   New->Flatness_Value = 0.0;
  2173.   
  2174.   New->Node_Tree = NULL;
  2175.   
  2176.   /*
  2177.    * NOTE: Control_Points[4][4] is initialized in Parse_Bicubic_Patch.
  2178.    * Bounding_Sphere_Center,Bounding_Sphere_Radius, Normal_Vector[], and
  2179.    * IPoint[] are initialized in Precompute_Patch_Values.
  2180.    */
  2181.   
  2182.   return (New);
  2183. }
  2184.  
  2185.  
  2186.  
  2187. /*****************************************************************************
  2188. *
  2189. * FUNCTION
  2190. *
  2191. *   Copy_Bicubic_Patch
  2192. *
  2193. * INPUT
  2194. *   
  2195. * OUTPUT
  2196. *   
  2197. * RETURNS
  2198. *   
  2199. * AUTHOR
  2200. *
  2201. *   Alexander Enzmann
  2202. *   
  2203. * DESCRIPTION
  2204. *
  2205. *   -
  2206. *
  2207. * CHANGES
  2208. *
  2209. *   -
  2210. *
  2211. ******************************************************************************/
  2212.  
  2213. static void *Copy_Bicubic_Patch(Object)
  2214. OBJECT *Object;
  2215. {
  2216.   int i, j;
  2217.   BICUBIC_PATCH *New;
  2218.   
  2219.   New = Create_Bicubic_Patch();
  2220.   
  2221.   /* Do not do *New = *Old so that Precompute works right */
  2222.   
  2223.   New->Patch_Type = ((BICUBIC_PATCH *)Object)->Patch_Type;
  2224.  
  2225.   New->U_Steps = ((BICUBIC_PATCH *)Object)->U_Steps;
  2226.   New->V_Steps = ((BICUBIC_PATCH *)Object)->V_Steps;
  2227.   
  2228.   for (i = 0; i < 4; i++)
  2229.   {
  2230.     for (j = 0; j < 4; j++)
  2231.     {
  2232.       Assign_Vector(New->Control_Points[i][j], ((BICUBIC_PATCH *)Object)->Control_Points[i][j]);
  2233.     }
  2234.   }
  2235.   
  2236.   New->Flatness_Value = ((BICUBIC_PATCH *)Object)->Flatness_Value;
  2237.   
  2238.   Precompute_Patch_Values(New);
  2239.   
  2240.   return (New);
  2241. }
  2242.  
  2243.  
  2244.  
  2245. /*****************************************************************************
  2246. *
  2247. * FUNCTION
  2248. *
  2249. *   Destroy_Bicubic_Patch
  2250. *
  2251. * INPUT
  2252. *   
  2253. * OUTPUT
  2254. *   
  2255. * RETURNS
  2256. *   
  2257. * AUTHOR
  2258. *
  2259. *   Alexander Enzmann
  2260. *   
  2261. * DESCRIPTION
  2262. *
  2263. *   -
  2264. *
  2265. * CHANGES
  2266. *
  2267. *   -
  2268. *
  2269. ******************************************************************************/
  2270.  
  2271. static void Destroy_Bicubic_Patch(Object)
  2272. OBJECT *Object;
  2273. {
  2274.   BICUBIC_PATCH *Patch;
  2275.   
  2276.   Patch = (BICUBIC_PATCH *)Object;
  2277.   
  2278.   if (Patch->Patch_Type != 0)
  2279.   {
  2280.     if (Patch->Node_Tree != NULL)
  2281.     {
  2282.       bezier_tree_deleter(Patch->Node_Tree);
  2283.     }
  2284.   }
  2285.   
  2286.   POV_FREE(Patch);
  2287. }
  2288.  
  2289.  
  2290.  
  2291. /*****************************************************************************
  2292. *
  2293. * FUNCTION
  2294. *
  2295. *   Compute_Bicubic_Patch_BBox
  2296. *
  2297. * INPUT
  2298. *
  2299. *   Bicubic_Patch - Bicubic patch
  2300. *   
  2301. * OUTPUT
  2302. *
  2303. *   Bicubic_Patch
  2304. *   
  2305. * RETURNS
  2306. *   
  2307. * AUTHOR
  2308. *
  2309. *   Dieter Bayer
  2310. *   
  2311. * DESCRIPTION
  2312. *
  2313. *   Calculate the bounding box of a bicubic patch.
  2314. *
  2315. * CHANGES
  2316. *
  2317. *   Aug 1994 : Creation.
  2318. *
  2319. ******************************************************************************/
  2320.  
  2321. void Compute_Bicubic_Patch_BBox(Bicubic_Patch)
  2322. BICUBIC_PATCH *Bicubic_Patch;
  2323. {
  2324.   int i, j;
  2325.   VECTOR Min, Max;
  2326.  
  2327.   Make_Vector(Min, BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
  2328.   Make_Vector(Max, -BOUND_HUGE, -BOUND_HUGE, -BOUND_HUGE);
  2329.  
  2330.   for (i = 0; i < 4; i++)
  2331.   {
  2332.     for (j = 0; j < 4; j++)
  2333.     {
  2334.       Min[X] = min(Min[X], Bicubic_Patch->Control_Points[i][j][X]);
  2335.       Min[Y] = min(Min[Y], Bicubic_Patch->Control_Points[i][j][Y]);
  2336.       Min[Z] = min(Min[Z], Bicubic_Patch->Control_Points[i][j][Z]);
  2337.       Max[X] = max(Max[X], Bicubic_Patch->Control_Points[i][j][X]);
  2338.       Max[Y] = max(Max[Y], Bicubic_Patch->Control_Points[i][j][Y]);
  2339.       Max[Z] = max(Max[Z], Bicubic_Patch->Control_Points[i][j][Z]);
  2340.     }
  2341.   }
  2342.   
  2343.   Make_BBox_from_min_max(Bicubic_Patch->BBox, Min, Max);
  2344. }
  2345.  
  2346.